﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ArduinoInterOp
{
    /*
     * 32 bit message:
     * 
     * |UNUSED|Command |Pin  | Value
        ****** ******** ******** **********
     * 
     * 
     */

    public class ArduinoResponse
    {
        public Dictionary<byte, ArduinoPinOperationData> ArduinoPinOperationDatasIndexedByPinNumber { get; internal set; }
        public Dictionary<ArduinoCommands, List<ArduinoPinOperationData>> ArduinoPinOperationDatasIndexedByCommand { get; internal set; }

        public IEnumerable<ArduinoPinOperationData> AllOperations
        {
            get { return ArduinoPinOperationDatasIndexedByPinNumber.Values; }
        }

        public ArduinoResponse()
        {
            ArduinoPinOperationDatasIndexedByPinNumber = new Dictionary<byte, ArduinoPinOperationData>();
            ArduinoPinOperationDatasIndexedByCommand = new Dictionary<ArduinoCommands, List<ArduinoPinOperationData>>();
        }

        internal void CreatePinDataFromString(string pinData)
        {
            var pinDatas = pinData.Trim().Split('-');

            foreach (var data in pinDatas)
            {
                if (string.IsNullOrEmpty(data))
                {
                    continue;
                }

                var pinOperationData = new ArduinoPinOperationData();
                pinOperationData.ParseNumericRepresentationString(data);

                this.ArduinoPinOperationDatasIndexedByPinNumber.Add(pinOperationData.Pin, pinOperationData);

                if (!ArduinoPinOperationDatasIndexedByCommand.ContainsKey(pinOperationData.CommandType))
                {
                    ArduinoPinOperationDatasIndexedByCommand.Add(pinOperationData.CommandType,
                                                                 new List<ArduinoPinOperationData>());
                }

                ArduinoPinOperationDatasIndexedByCommand[pinOperationData.CommandType].Add(pinOperationData);
            }
        }
    }

    public class ArduinoQueuedResponse : ArduinoResponse
    {
        public long OperationId { get; private set; }
        public long OperationExecutionTicks { get; private set; }

        public ArduinoQueuedResponse(string responseString)
        {
            var splittedResponse = responseString.Split(';');


            if (splittedResponse.Length == 2)
            {
                // && long.TryParse(splittedResponse[1], out operationTicks)

                var idAndExecutionTime = splittedResponse[1].Split('-');

                long operationId;
                long operationTicks;

                if (idAndExecutionTime.Length == 2 && long.TryParse(idAndExecutionTime[0], out operationId) && long.TryParse(idAndExecutionTime[1], out operationTicks))
                {
                    CreatePinDataFromString(splittedResponse[0]);

                    this.OperationId = operationId;
                    this.OperationExecutionTicks = operationTicks;
                }
            }
            else
            {
                //TODO
                throw new Exception();
            }
        }
    }
}